{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Cheminformatics Datasets \n",
    "https://github.com/GLambard/Molecules_Dataset_Collection/tree/master/latest"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Using TensorFlow backend.\n"
     ]
    }
   ],
   "source": [
    "from dl_util import *\n",
    "from ml_util import *\n",
    "\n",
    "from sklearn.preprocessing import StandardScaler\n",
    "from eval_class_util import *\n",
    "from run_eval import split_fit_plot_predict"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Extracting SMILES and converting into sequence "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [],
   "source": [
    "esol = pd.read_csv('eval_datasets/esol_v2.csv')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [],
   "source": [
    "esol_smiles = esol['smiles'].tolist()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(33, 98)"
      ]
     },
     "execution_count": 4,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "len_esol_smiles = []\n",
    "for SMILE in esol_smiles:\n",
    "    len_esol_smiles += [len(SMILE)]\n",
    "    \n",
    "max_len_esol = max(len_esol_smiles)\n",
    "\n",
    "esol_vocab_size = generate_onehot_encoding(esol_smiles,'vocab_size')\n",
    "esol_vocab_size, max_len_esol"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [],
   "source": [
    "esol_encodings = generate_onehot_encoding(esol_smiles)\n",
    "esol_sequences = sequence.pad_sequences(esol_encodings, maxlen=max_len_esol)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [],
   "source": [
    "#saveNumpy(esol_sequences, 'esol_sequences')\n",
    "#esol_sequences = loadNumpy(\"esol_sequences\")#X1 is esol_sequences\n",
    "esol_maccs = loadNumpy('esol_maccs') #X2\n",
    "esol_solubility = loadNumpy('esol_solubility') #Y"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [],
   "source": [
    "esol_solubility_standard = standardize_1d(esol_solubility)\n",
    "esol_solubility_normal = normalize_1d(esol_solubility)\n",
    "# saveNumpy(esol_solubility_standard, 'esol_standardized_solubility')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "_________________________________________________________________\n",
      "Layer (type)                 Output Shape              Param #   \n",
      "=================================================================\n",
      "embedding_5 (Embedding)      (None, 98, 32)            1056      \n",
      "_________________________________________________________________\n",
      "conv1d_9 (Conv1D)            (None, 98, 32)            3104      \n",
      "_________________________________________________________________\n",
      "max_pooling1d_9 (MaxPooling1 (None, 49, 32)            0         \n",
      "_________________________________________________________________\n",
      "conv1d_10 (Conv1D)           (None, 49, 32)            3104      \n",
      "_________________________________________________________________\n",
      "max_pooling1d_10 (MaxPooling (None, 24, 32)            0         \n",
      "_________________________________________________________________\n",
      "flatten_4 (Flatten)          (None, 768)               0         \n",
      "_________________________________________________________________\n",
      "dense_2 (Dense)              (None, 1)                 769       \n",
      "=================================================================\n",
      "Total params: 8,033\n",
      "Trainable params: 8,033\n",
      "Non-trainable params: 0\n",
      "_________________________________________________________________\n"
     ]
    }
   ],
   "source": [
    "layers=2\n",
    "optimizer =\"adam\"\n",
    "model_type =\"regression\"\n",
    "model = Sequential()\n",
    "model.add(Embedding(esol_vocab_size,  32, input_length=max_len_esol))\n",
    "model.add(Conv1D(filters=32, kernel_size=3, padding='same', activation='relu'))\n",
    "model.add(MaxPooling1D(pool_size=2))\n",
    "model.add(Conv1D(filters=32, kernel_size=3, padding='same', activation='relu'))\n",
    "model.add(MaxPooling1D(pool_size=2))\n",
    "if layers==3:\n",
    "    model.add(Conv1D(filters=32, kernel_size=3, padding='same', activation='relu'))\n",
    "    model.add(MaxPooling1D(pool_size=2))\n",
    "model.add(Flatten())\n",
    "# if optimizer == \"adam\" and lr!= 0.001:\n",
    "#     print(\"Setting learning rate to\"+str(lr))\n",
    "#     optimizer = tf.train.AdamOptimizer(lr)\n",
    "\n",
    "if model_type == \"classification\":\n",
    "    model.add(Dense(1,activation='sigmoid'))\n",
    "    model.compile(loss='binary_crossentropy',optimizer=optimizer,metrics=['acc', precision,recall,auc])\n",
    "else:\n",
    "    model.add(Dense(1))\n",
    "    model.compile(loss='mse',optimizer=optimizer, metrics=['mape'])\n",
    "model.summary()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "metadata": {},
   "outputs": [],
   "source": [
    "X1_train, X1_test, y_train, y_test = train_test_split(esol_sequences, esol_solubility_standard, random_state=1024)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Train on 761 samples, validate on 85 samples\n",
      "Epoch 1/40\n",
      "761/761 [==============================] - 2s 2ms/step - loss: 0.0295 - mean_absolute_percentage_error: 24.9151 - val_loss: 0.0050 - val_mean_absolute_percentage_error: 9.8132\n",
      "Epoch 2/40\n",
      "761/761 [==============================] - 1s 2ms/step - loss: 0.0050 - mean_absolute_percentage_error: 12.0236 - val_loss: 0.0024 - val_mean_absolute_percentage_error: 6.4121\n",
      "Epoch 3/40\n",
      "761/761 [==============================] - 1s 2ms/step - loss: 0.0032 - mean_absolute_percentage_error: 9.3108 - val_loss: 0.0016 - val_mean_absolute_percentage_error: 5.1381\n",
      "Epoch 4/40\n",
      "761/761 [==============================] - 1s 2ms/step - loss: 0.0028 - mean_absolute_percentage_error: 8.7759 - val_loss: 0.0029 - val_mean_absolute_percentage_error: 7.3323\n",
      "Epoch 5/40\n",
      "761/761 [==============================] - 1s 2ms/step - loss: 0.0019 - mean_absolute_percentage_error: 7.0532 - val_loss: 0.0015 - val_mean_absolute_percentage_error: 4.9594\n",
      "Epoch 6/40\n",
      "761/761 [==============================] - 1s 2ms/step - loss: 0.0015 - mean_absolute_percentage_error: 6.6633 - val_loss: 0.0020 - val_mean_absolute_percentage_error: 5.7743\n",
      "Epoch 7/40\n",
      "761/761 [==============================] - 1s 2ms/step - loss: 0.0015 - mean_absolute_percentage_error: 5.6096 - val_loss: 0.0015 - val_mean_absolute_percentage_error: 5.0133\n",
      "Epoch 8/40\n",
      "761/761 [==============================] - 1s 2ms/step - loss: 0.0014 - mean_absolute_percentage_error: 5.9673 - val_loss: 0.0017 - val_mean_absolute_percentage_error: 5.9303\n",
      "Epoch 9/40\n",
      "761/761 [==============================] - 1s 2ms/step - loss: 0.0013 - mean_absolute_percentage_error: 5.2090 - val_loss: 0.0021 - val_mean_absolute_percentage_error: 6.1718\n",
      "Epoch 10/40\n",
      "761/761 [==============================] - 1s 2ms/step - loss: 9.6179e-04 - mean_absolute_percentage_error: 4.3125 - val_loss: 0.0013 - val_mean_absolute_percentage_error: 4.8097\n",
      "Epoch 11/40\n",
      "761/761 [==============================] - 1s 2ms/step - loss: 8.4386e-04 - mean_absolute_percentage_error: 4.6580 - val_loss: 0.0015 - val_mean_absolute_percentage_error: 4.5137\n",
      "Epoch 12/40\n",
      "761/761 [==============================] - 1s 2ms/step - loss: 8.8554e-04 - mean_absolute_percentage_error: 4.5033 - val_loss: 0.0012 - val_mean_absolute_percentage_error: 4.1965\n",
      "Epoch 13/40\n",
      "761/761 [==============================] - 1s 2ms/step - loss: 9.8601e-04 - mean_absolute_percentage_error: 5.1865 - val_loss: 0.0013 - val_mean_absolute_percentage_error: 4.8773\n",
      "Epoch 14/40\n",
      "761/761 [==============================] - 1s 2ms/step - loss: 9.9901e-04 - mean_absolute_percentage_error: 4.5204 - val_loss: 0.0011 - val_mean_absolute_percentage_error: 4.4111\n",
      "Epoch 15/40\n",
      "761/761 [==============================] - 1s 2ms/step - loss: 8.7976e-04 - mean_absolute_percentage_error: 4.6809 - val_loss: 0.0011 - val_mean_absolute_percentage_error: 4.1953\n",
      "Epoch 16/40\n",
      "761/761 [==============================] - 1s 2ms/step - loss: 7.6075e-04 - mean_absolute_percentage_error: 3.9514 - val_loss: 0.0012 - val_mean_absolute_percentage_error: 4.1904\n",
      "Epoch 17/40\n",
      "761/761 [==============================] - 1s 2ms/step - loss: 8.3397e-04 - mean_absolute_percentage_error: 4.4779 - val_loss: 0.0037 - val_mean_absolute_percentage_error: 8.4792\n",
      "Epoch 18/40\n",
      "761/761 [==============================] - 1s 2ms/step - loss: 0.0011 - mean_absolute_percentage_error: 5.2593 - val_loss: 0.0012 - val_mean_absolute_percentage_error: 4.5543\n",
      "Epoch 19/40\n",
      "761/761 [==============================] - 1s 2ms/step - loss: 6.7976e-04 - mean_absolute_percentage_error: 4.0522 - val_loss: 0.0016 - val_mean_absolute_percentage_error: 5.5311\n",
      "Epoch 20/40\n",
      "761/761 [==============================] - 1s 2ms/step - loss: 5.5103e-04 - mean_absolute_percentage_error: 3.4755 - val_loss: 0.0016 - val_mean_absolute_percentage_error: 5.1821\n",
      "Epoch 21/40\n",
      "761/761 [==============================] - 1s 2ms/step - loss: 7.3113e-04 - mean_absolute_percentage_error: 4.1080 - val_loss: 0.0014 - val_mean_absolute_percentage_error: 5.3772\n",
      "Epoch 22/40\n",
      "761/761 [==============================] - 1s 2ms/step - loss: 6.7663e-04 - mean_absolute_percentage_error: 3.9445 - val_loss: 0.0013 - val_mean_absolute_percentage_error: 4.7989\n",
      "Epoch 23/40\n",
      "761/761 [==============================] - 1s 2ms/step - loss: 7.5646e-04 - mean_absolute_percentage_error: 4.1260 - val_loss: 0.0016 - val_mean_absolute_percentage_error: 5.2673\n",
      "Epoch 24/40\n",
      "761/761 [==============================] - 1s 2ms/step - loss: 7.4198e-04 - mean_absolute_percentage_error: 4.0078 - val_loss: 0.0012 - val_mean_absolute_percentage_error: 4.3807\n",
      "Epoch 25/40\n",
      "761/761 [==============================] - 1s 2ms/step - loss: 5.5860e-04 - mean_absolute_percentage_error: 3.4534 - val_loss: 0.0017 - val_mean_absolute_percentage_error: 5.4413\n",
      "Epoch 26/40\n",
      "761/761 [==============================] - 1s 2ms/step - loss: 6.2360e-04 - mean_absolute_percentage_error: 3.3812 - val_loss: 0.0010 - val_mean_absolute_percentage_error: 3.6592\n",
      "Epoch 27/40\n",
      "761/761 [==============================] - 1s 2ms/step - loss: 5.7258e-04 - mean_absolute_percentage_error: 3.6815 - val_loss: 0.0018 - val_mean_absolute_percentage_error: 5.6362\n",
      "Epoch 28/40\n",
      "761/761 [==============================] - 1s 2ms/step - loss: 5.8909e-04 - mean_absolute_percentage_error: 3.4160 - val_loss: 0.0013 - val_mean_absolute_percentage_error: 4.6645\n",
      "Epoch 29/40\n",
      "761/761 [==============================] - 1s 2ms/step - loss: 5.1086e-04 - mean_absolute_percentage_error: 3.2245 - val_loss: 0.0013 - val_mean_absolute_percentage_error: 4.2935\n",
      "Epoch 30/40\n",
      "761/761 [==============================] - 1s 2ms/step - loss: 5.4712e-04 - mean_absolute_percentage_error: 3.3096 - val_loss: 0.0021 - val_mean_absolute_percentage_error: 6.5570\n",
      "Epoch 31/40\n",
      "761/761 [==============================] - 1s 2ms/step - loss: 7.0207e-04 - mean_absolute_percentage_error: 3.9981 - val_loss: 0.0023 - val_mean_absolute_percentage_error: 5.6201\n",
      "Epoch 32/40\n",
      "761/761 [==============================] - 1s 2ms/step - loss: 7.0786e-04 - mean_absolute_percentage_error: 3.7303 - val_loss: 0.0013 - val_mean_absolute_percentage_error: 4.5645\n",
      "Epoch 33/40\n",
      "761/761 [==============================] - 1s 2ms/step - loss: 6.2724e-04 - mean_absolute_percentage_error: 3.8565 - val_loss: 0.0025 - val_mean_absolute_percentage_error: 7.1098\n",
      "Epoch 34/40\n",
      "761/761 [==============================] - 1s 2ms/step - loss: 7.0094e-04 - mean_absolute_percentage_error: 3.6462 - val_loss: 0.0018 - val_mean_absolute_percentage_error: 5.8380\n",
      "Epoch 35/40\n",
      "761/761 [==============================] - 1s 2ms/step - loss: 8.5280e-04 - mean_absolute_percentage_error: 4.6849 - val_loss: 0.0014 - val_mean_absolute_percentage_error: 5.1484\n",
      "Epoch 36/40\n",
      "761/761 [==============================] - 1s 2ms/step - loss: 6.5114e-04 - mean_absolute_percentage_error: 4.0022 - val_loss: 0.0015 - val_mean_absolute_percentage_error: 5.7171\n",
      "Epoch 37/40\n",
      "761/761 [==============================] - 1s 2ms/step - loss: 5.9036e-04 - mean_absolute_percentage_error: 4.0134 - val_loss: 0.0015 - val_mean_absolute_percentage_error: 5.3000\n",
      "Epoch 38/40\n",
      "761/761 [==============================] - 1s 2ms/step - loss: 7.9207e-04 - mean_absolute_percentage_error: 4.4448 - val_loss: 8.9923e-04 - val_mean_absolute_percentage_error: 3.7155\n",
      "Epoch 39/40\n",
      "761/761 [==============================] - 1s 2ms/step - loss: 4.0095e-04 - mean_absolute_percentage_error: 3.1235 - val_loss: 9.1252e-04 - val_mean_absolute_percentage_error: 3.8889\n",
      "Epoch 40/40\n",
      "761/761 [==============================] - 1s 2ms/step - loss: 3.6088e-04 - mean_absolute_percentage_error: 2.6163 - val_loss: 0.0011 - val_mean_absolute_percentage_error: 4.0780\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "<keras.callbacks.History at 0x7fd60abcc050>"
      ]
     },
     "execution_count": 22,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "model.fit(X1_train, y_train, shuffle=True, validation_split=0.1,\\\n",
    "                        epochs=40, batch_size=4, verbose=1)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 44,
   "metadata": {},
   "outputs": [],
   "source": [
    "y_predict = model.predict(X1_test).reshape(1,-1)[0]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 42,
   "metadata": {},
   "outputs": [],
   "source": [
    "y_test = np.array(y_test)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 49,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(numpy.ndarray, numpy.ndarray)"
      ]
     },
     "execution_count": 49,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "type(y_predict), type(y_test)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 27,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[0.8193273417956083,\n",
       " 0.562308903919207,\n",
       " 0.8603724636338368,\n",
       " 0.6301306402297786,\n",
       " 0.7172241267488187]"
      ]
     },
     "execution_count": 27,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "y_test[:5]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "cnn_model\n",
      "WARNING:tensorflow:From /usr/local/lib/python2.7/dist-packages/tensorflow/python/util/deprecation.py:497: calling conv1d (from tensorflow.python.ops.nn_ops) with data_format=NHWC is deprecated and will be removed in a future version.\n",
      "Instructions for updating:\n",
      "`NHWC` for data_format is deprecated, use `NWC` instead\n",
      "_________________________________________________________________\n",
      "Layer (type)                 Output Shape              Param #   \n",
      "=================================================================\n",
      "embedding_1 (Embedding)      (None, 98, 32)            1056      \n",
      "_________________________________________________________________\n",
      "conv1d_1 (Conv1D)            (None, 98, 32)            3104      \n",
      "_________________________________________________________________\n",
      "max_pooling1d_1 (MaxPooling1 (None, 49, 32)            0         \n",
      "_________________________________________________________________\n",
      "conv1d_2 (Conv1D)            (None, 49, 32)            3104      \n",
      "_________________________________________________________________\n",
      "max_pooling1d_2 (MaxPooling1 (None, 24, 32)            0         \n",
      "_________________________________________________________________\n",
      "flatten_1 (Flatten)          (None, 768)               0         \n",
      "_________________________________________________________________\n",
      "dense_1 (Dense)              (None, 1)                 769       \n",
      "=================================================================\n",
      "Total params: 8,033\n",
      "Trainable params: 8,033\n",
      "Non-trainable params: 0\n",
      "_________________________________________________________________\n",
      "Train on 761 samples, validate on 85 samples\n",
      "Epoch 1/10\n",
      "761/761 [==============================] - 3s 3ms/step - loss: 0.0345 - mean_absolute_percentage_error: 29.6910 - val_loss: 0.0049 - val_mean_absolute_percentage_error: 10.3243\n",
      "Epoch 2/10\n",
      "761/761 [==============================] - 1s 2ms/step - loss: 0.0054 - mean_absolute_percentage_error: 12.0102 - val_loss: 0.0029 - val_mean_absolute_percentage_error: 7.2247\n",
      "Epoch 3/10\n",
      "761/761 [==============================] - 1s 2ms/step - loss: 0.0039 - mean_absolute_percentage_error: 9.0701 - val_loss: 0.0020 - val_mean_absolute_percentage_error: 5.8489\n",
      "Epoch 4/10\n",
      "761/761 [==============================] - 1s 2ms/step - loss: 0.0027 - mean_absolute_percentage_error: 7.8105 - val_loss: 0.0046 - val_mean_absolute_percentage_error: 10.1544\n",
      "Epoch 5/10\n",
      "761/761 [==============================] - 1s 2ms/step - loss: 0.0022 - mean_absolute_percentage_error: 7.1018 - val_loss: 0.0017 - val_mean_absolute_percentage_error: 5.7479\n",
      "Epoch 6/10\n",
      "761/761 [==============================] - 1s 2ms/step - loss: 0.0018 - mean_absolute_percentage_error: 6.2539 - val_loss: 0.0021 - val_mean_absolute_percentage_error: 6.2329\n",
      "Epoch 7/10\n",
      "761/761 [==============================] - 1s 2ms/step - loss: 0.0013 - mean_absolute_percentage_error: 5.3584 - val_loss: 0.0016 - val_mean_absolute_percentage_error: 5.3698\n",
      "Epoch 8/10\n",
      "761/761 [==============================] - 1s 2ms/step - loss: 0.0013 - mean_absolute_percentage_error: 5.6180 - val_loss: 0.0017 - val_mean_absolute_percentage_error: 5.1842\n",
      "Epoch 9/10\n",
      "761/761 [==============================] - 1s 2ms/step - loss: 0.0015 - mean_absolute_percentage_error: 5.9957 - val_loss: 0.0023 - val_mean_absolute_percentage_error: 6.1075\n",
      "Epoch 10/10\n",
      "761/761 [==============================] - 1s 2ms/step - loss: 0.0015 - mean_absolute_percentage_error: 5.8850 - val_loss: 0.0018 - val_mean_absolute_percentage_error: 5.7964\n",
      "282/282 [==============================] - 0s 116us/step\n",
      "('Test mape%:', 6.8)\n",
      "('eval_mape%', 673984.5756327447)\n",
      "('mae', 0.038700525)\n",
      "('y_test', array([0.81932735, 0.5623089 , 0.8603725 , 0.63013065, 0.7172241 ],\n",
      "      dtype=float32))\n",
      "('y_predict', array([0.81346005, 0.57375336, 0.90936947, 0.65371716, 0.72972506],\n",
      "      dtype=float32))\n",
      "(282, 282)\n",
      "('History saved successfully', 'history_esol_cnn_model_dropout_0_epochs_10_batch_4_lr_0.001.pkl')\n",
      "Stats saved in model/stats_esol_cnn_model_dropout_0_epochs_10_batch_4_lr_0.001\n"
     ]
    },
    {
     "data": {
      "image/png": "iVBORw0KGgoAAAANSUhEUgAAAYIAAAEKCAYAAAAfGVI8AAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEgAACxIB0t1+/AAAADl0RVh0U29mdHdhcmUAbWF0cGxvdGxpYiB2ZXJzaW9uIDIuMi4yLCBodHRwOi8vbWF0cGxvdGxpYi5vcmcvhp/UCwAAIABJREFUeJzt3Xl8VeW56PHfk515IDNjhCAiMwLmACoogwNtFUuPx2pxrC3n2h7ntlpPe/S0p/d6W6vU1lqHOrQO1Kui1tZZEIcWC0iRQQQRkDkzmXey89w/1krYQZIsQvZeSfbz/XzWZ6+19hqebGU/+x3W+4qqYowxJnbF+R2AMcYYf1kiMMaYGGeJwBhjYpwlAmOMiXGWCIwxJsZZIjDGmBhnicAYY2KcJQJjjIlxlgiMMSbGxfsdgBd5eXlaWFjodxjGGNOrrF69ukRV8zs7rlckgsLCQlatWuV3GMYY06uIyA4vx1nVkDHGxDhLBMYYE+MsERhjTIzrFW0ExpjIaWxsZNeuXdTX1/sdiumi5ORkCgoKSEhI6NL5lgiMiXG7du0iIyODwsJCRMTvcMxRUlVKS0vZtWsXw4cP79I1rGrImBhXX19Pbm6uJYFeSkTIzc09phKdJQJjjCWBXu5Y//tZIjDGmBhnicAY45vS0lImTZrEpEmTGDhwIEOGDGndDgaDnq5x5ZVXsnnzZs/3fOihh8jPz2+9z6RJk47q/L7IGouNMb7Jzc1l7dq1ANx+++2kp6fzve99r80xqoqqEhd35N+tjzzyyFHfd+HChSxevLjd95uamoiPP/T12FkM4UKhEIFA4Khj8pOVCIwxPc7WrVsZO3YsCxcuZNy4cezdu5dFixZRVFTEuHHj+MlPftJ67IwZM1i7di1NTU1kZWVxyy23cNJJJ3HKKadw4MABz/d84403mDVrFueeey4TJkw4YgyPP/44EyZMYPz48dx6660Arfe9/vrrmThxIh988EG3fx6RZiUCY0yr//7zBjbuOdit1xw7uB+3nTfuqM/7+OOP+cMf/kBRUREAd9xxBzk5OTQ1NTF79mwuuOACxo4d2+acyspKzjjjDO644w5uvPFGHn74YW655ZYvXPuJJ55g+fLlrdstX96rVq1i48aNDB06lK1bt7aJYdeuXfzoRz9i1apVZGZmcuaZZ/LSSy8xb948KisrOf300zssZfRkViIwxvRII0aMaE0CAE899RRTpkxhypQpbNq0iY0bN37hnJSUFL70pS8BcPLJJ7N9+/YjXnvhwoWsXbu2dUlMTATglFNOYejQoUeMYeXKlcyZM4e8vDwSEhL4xje+wYoVKwBITExkwYIF3fJ3+8FKBMaYVl355R4paWlpretbtmzhV7/6FR988AFZWVlccsklR+w33/KFDhAIBGhqauryPY+03Z6UlJRe3QXXSgTGmB7v4MGDZGRk0K9fP/bu3curr74a9RimTZvGsmXLKC0tpampiSVLlnDGGWdEPY5IsBKBMabHmzJlCmPHjmX06NEMGzaM00477Ziud3gbwf3339/pOQUFBfz0pz9l1qxZqCrnnXceX/nKV4661NETiar6HUOnioqK1CamMSYyNm3axJgxY/wOwxyjI/13FJHVqlrUzimtrGrIGGNinCUCY4yJcZYIjDEmxnlOBCJygog8LiLPisgpkQzKGGNM9LTba0hEklU1vKPuT4EfuOt/BiZFMjBjjDHR0VGJ4M8iclnYdiNQCAwDQpEMyhhjTPR0lAjmAf1E5BUROR34HnAOsABYGI3gjDF92+zZs7/wcNjixYu5+uqrOzwvPT0dgD179nDBBRcc8ZhZs2bRWbfzxYsXU1tb27r95S9/mYqKCi+hd+j2229vM6T2pEmTuuW6kdJuIlDVkKr+Bvg6MB/4FfCIqt6kqh9HK0BjTN918cUXs2TJkjb7lixZwsUXX+zp/MGDB/PMM890+f6HJ4K//vWvZGVldfl64W644YY24xkdft3DH0Tz+mCaqtLc3NwtMbZoNxGIyDQReQa4D3gU+BHwMxH5pYh0zydljIlpF1xwAX/5y19aJ6HZvn07e/bsYebMmVRXVzN37lymTJnChAkTeOGFF75w/vbt2xk/fjwAdXV1XHTRRYwZM4YFCxZQV1fXetzVV1/dOoT1bbfdBsA999zDnj17mD17NrNnzwagsLCQkpISAO666y7Gjx/P+PHjW0cV3b59O2PGjOHb3/4248aN4+yzz25zn848+uijzJ8/nzlz5jB37lyWL1/OzJkzmT9/futIqu3dd9SoUVx22WWMHz+ezz///Kg+5850NMTE/cCXgXScksBpwEUicgbwJ5xqImNMX/LyLbDvo+695sAJ8KU7jvhWTk4OU6dO5eWXX+b8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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "y_test,y_predict = split_fit_plot_predict(cnn_model,  esol_sequences, esol_maccs, esol_solubility_standard, esol_vocab_size, max_len_esol, \"esol\",\\\n",
    "                      batch_size=4, epochs=10)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "(0.0, 24)\n"
     ]
    }
   ],
   "source": [
    "for i in range(len(y_test)):\n",
    "    item = y_test[i]\n",
    "    if item == 0:\n",
    "        print(item,i)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [],
   "source": [
    "for i in range(len(y_predict)):\n",
    "    item = y_predict[i]\n",
    "    if item == 0:\n",
    "        print(item,i)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Predictions "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "cnn_model\n",
      "_________________________________________________________________\n",
      "Layer (type)                 Output Shape              Param #   \n",
      "=================================================================\n",
      "embedding_4 (Embedding)      (None, 98, 32)            1056      \n",
      "_________________________________________________________________\n",
      "conv1d_7 (Conv1D)            (None, 98, 32)            3104      \n",
      "_________________________________________________________________\n",
      "max_pooling1d_7 (MaxPooling1 (None, 49, 32)            0         \n",
      "_________________________________________________________________\n",
      "conv1d_8 (Conv1D)            (None, 49, 32)            3104      \n",
      "_________________________________________________________________\n",
      "max_pooling1d_8 (MaxPooling1 (None, 24, 32)            0         \n",
      "_________________________________________________________________\n",
      "flatten_4 (Flatten)          (None, 768)               0         \n",
      "_________________________________________________________________\n",
      "dense_4 (Dense)              (None, 1)                 769       \n",
      "=================================================================\n",
      "Total params: 8,033\n",
      "Trainable params: 8,033\n",
      "Non-trainable params: 0\n",
      "_________________________________________________________________\n",
      "Train on 761 samples, validate on 85 samples\n",
      "Epoch 1/40\n",
      "761/761 [==============================] - 1s 2ms/step - loss: 2.5875 - mean_absolute_percentage_error: 89.1865 - val_loss: 0.7451 - val_mean_absolute_percentage_error: 35.2441\n",
      "Epoch 2/40\n",
      "761/761 [==============================] - 1s 2ms/step - loss: 0.6387 - mean_absolute_percentage_error: 51.4896 - val_loss: 0.3482 - val_mean_absolute_percentage_error: 23.2861\n",
      "Epoch 3/40\n",
      "761/761 [==============================] - 1s 2ms/step - loss: 0.3723 - mean_absolute_percentage_error: 37.0239 - val_loss: 0.3707 - val_mean_absolute_percentage_error: 21.1425\n",
      "Epoch 4/40\n",
      "761/761 [==============================] - 1s 2ms/step - loss: 0.3144 - mean_absolute_percentage_error: 31.3107 - val_loss: 0.2538 - val_mean_absolute_percentage_error: 18.0644\n",
      "Epoch 5/40\n",
      "761/761 [==============================] - 1s 2ms/step - loss: 0.2503 - mean_absolute_percentage_error: 27.5207 - val_loss: 0.2139 - val_mean_absolute_percentage_error: 17.8918\n",
      "Epoch 6/40\n",
      "761/761 [==============================] - 1s 2ms/step - loss: 0.2099 - mean_absolute_percentage_error: 25.6294 - val_loss: 0.1943 - val_mean_absolute_percentage_error: 16.0306\n",
      "Epoch 7/40\n",
      "761/761 [==============================] - 1s 2ms/step - loss: 0.1728 - mean_absolute_percentage_error: 22.3408 - val_loss: 0.1807 - val_mean_absolute_percentage_error: 15.6456\n",
      "Epoch 8/40\n",
      "761/761 [==============================] - 1s 2ms/step - loss: 0.1629 - mean_absolute_percentage_error: 22.4311 - val_loss: 0.1669 - val_mean_absolute_percentage_error: 14.8036\n",
      "Epoch 9/40\n",
      "761/761 [==============================] - 1s 2ms/step - loss: 0.1382 - mean_absolute_percentage_error: 19.7654 - val_loss: 0.2326 - val_mean_absolute_percentage_error: 16.2042\n",
      "Epoch 10/40\n",
      "761/761 [==============================] - 1s 2ms/step - loss: 0.1400 - mean_absolute_percentage_error: 19.1311 - val_loss: 0.2118 - val_mean_absolute_percentage_error: 16.1639\n",
      "Epoch 11/40\n",
      "761/761 [==============================] - 1s 2ms/step - loss: 0.1274 - mean_absolute_percentage_error: 17.3548 - val_loss: 0.1716 - val_mean_absolute_percentage_error: 14.8009\n",
      "Epoch 12/40\n",
      "761/761 [==============================] - 1s 2ms/step - loss: 0.1203 - mean_absolute_percentage_error: 18.2239 - val_loss: 0.1743 - val_mean_absolute_percentage_error: 14.7915\n",
      "Epoch 13/40\n",
      "761/761 [==============================] - 1s 2ms/step - loss: 0.0951 - mean_absolute_percentage_error: 15.9154 - val_loss: 0.2159 - val_mean_absolute_percentage_error: 15.5972\n",
      "282/282 [==============================] - 0s 85us/step\n",
      "('Test mape%:', 24.23025902957781)\n",
      "('History saved successfully', 'history_esol_cnn_model_dropout_0_epochs_40_batch_4_lr_0.001.pkl')\n",
      "Stats saved in model/stats_esol_cnn_model_dropout_0_epochs_40_batch_4_lr_0.001\n"
     ]
    },
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "split_fit_plot_predict(cnn_model,  esol_sequences, esol_maccs, esol_solubility, esol_vocab_size, max_len_esol, \"esol\",\\\n",
    "                      batch_size=4, epochs=40)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "rnn_model\n"
     ]
    },
    {
     "ename": "NameError",
     "evalue": "global name 'model_type' is not defined",
     "output_type": "error",
     "traceback": [
      "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
      "\u001b[0;31mNameError\u001b[0m                                 Traceback (most recent call last)",
      "\u001b[0;32m<ipython-input-7-94cd5b37b3a4>\u001b[0m in \u001b[0;36m<module>\u001b[0;34m()\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0msplit_fit_plot_predict\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mrnn_model\u001b[0m\u001b[0;34m,\u001b[0m  \u001b[0mesol_sequences\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mesol_maccs\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mesol_solubility\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mesol_vocab_size\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mmax_len_esol\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m\"esol\"\u001b[0m\u001b[0;34m,\u001b[0m                      \u001b[0mbatch_size\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;36m4\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mepochs\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;36m40\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m",
      "\u001b[0;32m/home/apx748/CEP/run_eval.pyc\u001b[0m in \u001b[0;36msplit_fit_plot_predict\u001b[0;34m(model_arch, X1, X2, Y, vocab, max_len, prefix, dropout, gate, optimizer, lr, epochs, batch_size)\u001b[0m\n\u001b[1;32m     48\u001b[0m             \u001b[0mmodel_name\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mmodel_name\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mreplace\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m\"rnn\"\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0mgate\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m     49\u001b[0m         \u001b[0;32melse\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m---> 50\u001b[0;31m              \u001b[0mmodel\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mmodel_arch\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mdropout\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mdropout\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0moptimizer\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0moptimizer\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0mlr\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mlr\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0mvocab\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mvocab\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0mmax_len\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mmax_len\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m     51\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m     52\u001b[0m         history = model.fit(X1_train, y_train, shuffle=True, validation_split=0.1,\\\n",
      "\u001b[0;32m/home/apx748/CEP/eval_class_util.py\u001b[0m in \u001b[0;36mrnn_model\u001b[0;34m(optimizer, lr, dropout, gate, gated_layers, num_gated_connections, vocab, embedding_length, max_len)\u001b[0m\n\u001b[1;32m     49\u001b[0m         \u001b[0moptimizer\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mtf\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mtrain\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mAdamOptimizer\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mlr\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m     50\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m---> 51\u001b[0;31m     \u001b[0;32mif\u001b[0m \u001b[0mmodel_type\u001b[0m \u001b[0;34m==\u001b[0m \u001b[0;34m\"classification\"\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m     52\u001b[0m         \u001b[0mmodel\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0madd\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mDense\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;36m1\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0mactivation\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;34m'sigmoid'\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m     53\u001b[0m         \u001b[0mmodel\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mcompile\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mloss\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;34m'binary_crossentropy'\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0moptimizer\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0moptimizer\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0mmetrics\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;34m'acc'\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mprecision\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0mrecall\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0mauc\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
      "\u001b[0;31mNameError\u001b[0m: global name 'model_type' is not defined"
     ]
    }
   ],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 2",
   "language": "python",
   "name": "python2"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 2
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython2",
   "version": "2.7.12"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
